# coding:utf-8

from . import api
from ihome.models import Area, House, Facility, HouseImage, User
from ihome.utils.response_code import RET
from flask import current_app, jsonify, g, request, session
from ihome import redis_store, constants, db
import json
from ihome.utils.commons import login_required, upload_image


@api.route('/house/areas', methods=['GET'])
@login_required
def get_area_info():
    """获取城区信息"""
    # 先尝试从Redis中获取缓存数据
    try:
        areas_json = redis_store.get('area_info')
    except Exception as e:
        current_app.logger.error(e)
        areas_json = None

    # redis中数据为空
    if areas_json is None:
        # 查询数据库，获取城区信息
        try:
            areas_list = Area.query.all()
        except Exception as e:
            current_app.logger(e)
            return jsonify(errno=RET.DBERR, errmsg="查询城区信息异常")
        # 遍历列表，转换成字典
        areas = []
        for area in areas_list:
            areas.append(area.to_dict())
        # 将数据转换成json
        areas_json = json.dumps(areas)
        # 将数据在redis中保存一份缓存
        try:
            redis_store.setex('area_info', constants.AREA_INFO_REDIS_EXPIRES, areas_json)
        except Exception as e:
            current_app.logger.error(e)

    return jsonify(errno=RET.OK, errmsg='查询城区信息成功', data={'areas': areas_json})


@api.route('/house/facility', methods=['GET'])
@login_required
def get_facility_info():
    """获取配套设施信息"""
    # 先尝试从Redis中获取缓存数据
    try:
        facility_json = redis_store.get('facility_info')
    except Exception as e:
        current_app.logger.error(e)
        facility_json = None

    # redis中数据为空
    if facility_json is None:
        # 查询数据库，获取城区信息
        try:
            facility_list = Facility.query.all()
        except Exception as e:
            current_app.logger(e)
            return jsonify(errno=RET.DBERR, errmsg="查询配套设施信息异常")
        # 遍历列表，转换成字典
        facility = []
        for f in facility_list:
            facility.append(f.to_dict())
        # 将数据转换成json
        facility_json = json.dumps(facility)
        # 将数据在redis中保存一份缓存
        try:
            redis_store.setex('facility_info', constants.FACILITY_INFO_REDIS_EXPIRES, facility_json)
        except Exception as e:
            current_app.logger.error(e)

    return jsonify(errno=RET.OK, errmsg='查询配套设施信息成功', data={'facility_info': facility_json})


@api.route('/house/info', methods=['POST'])
@login_required
def save_house_info():
    user_id = g.uid
    user = User.query.get(user_id)
    if not user.check_auth():
        return jsonify(errno=RET.DATAEXIST, errmsg='您尚未实名认证')
    # 获取参数
    house_data = request.get_json()
    if house_data is None:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    title = house_data.get("title")  # 房屋名称标题
    price = house_data.get("price")  # 房屋单价
    area_id = house_data.get("area_id")  # 房屋所属城区的编号
    address = house_data.get("address")  # 房屋地址
    room_count = house_data.get("room_count")  # 房屋包含的房间数目
    acreage = house_data.get("acreage")  # 房屋面积
    unit = house_data.get("unit")  # 房屋布局（几室几厅)
    capacity = house_data.get("capacity")  # 房屋容纳人数
    beds = house_data.get("beds")  # 房屋卧床数目
    deposit = house_data.get("deposit")  # 押金
    min_days = house_data.get("min_days")  # 最小入住天数
    max_days = house_data.get("max_days")  # 最大入住天数

    # 校验参数
    if not all(
            [title, price, area_id, address, room_count, acreage, unit, capacity, beds, deposit, min_days, max_days]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")
    # 判断单价和押金格式是否正确
    # 前端传送过来的金额参数是以元为单位，浮点数，数据库中保存的是以分为单位，整数
    try:
        price = int(float(price) * 100)
        deposit = int(float(deposit) * 100)
    except Exception as e:
        return jsonify(errno=RET.DATAERR, errmsg="参数有误")
    # 保存信息
    house = House(
        user_id=user_id,
        area_id=area_id,
        title=title,
        price=price,
        address=address,
        room_count=room_count,
        acreage=acreage,
        unit=unit,
        capacity=capacity,
        beds=beds,
        deposit=deposit,
        min_days=min_days,
        max_days=max_days
    )
    # 处理房屋的设施信息
    facility_id_list = house_data.get('facility')
    if facility_id_list:
        # 表示用户勾选了房屋设施
        # 过滤用户传送的不合法的设施id
        try:
            facility_list = Facility.query.filter(Facility.id.in_(facility_id_list)).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="数据库异常")
        if facility_list:
            house.facilities = facility_list

    # 保存到数据库
    try:
        db.session.add(house)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存数据失败")

    # 返回
    return jsonify(errno=RET.OK, errmsg="保存成功", data={"house_id": house.id})


@api.route("/house/image", methods=["POST"])
@login_required
def save_house_image():
    """保存房屋的图片"""
    user = User.query.get(g.uid)
    if not user.check_auth():
        return jsonify(errno=RET.DATAEXIST, errmsg='您尚未实名认证')
    # 获取参数 房屋的图片、房屋编号
    house_id = request.form.get('house_id')
    house_image_data = request.files.get('house_image')

    # 校验参数
    if not all([house_id, house_image_data]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 判断房屋是否存在
    try:
        house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")

    if house is None:
        return jsonify(errno=RET.NODATA, errmsg="房屋不存在")

    # 上传房屋图片到七牛云中
    try:
        file_name = upload_image(house_image_data.read())
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="保存房屋图片失败")

    # 保存图片信息到数据库中
    house_image = HouseImage(
        house_id=house_id,
        url=file_name
    )
    db.session.add(house_image)

    # 处理房屋基本信息中的主图片
    if not house.index_image_url:
        house.index_image_url = file_name
        db.session.add(house)

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存图片信息失败")

    return jsonify(errno=RET.OK, errmsg="保存图片成功", data={"image_url": file_name})


@api.route('/user/houses', methods=['GET'])
@login_required
def get_user_houses():
    """获取房东发布的房源信息"""
    try:
        user = User.query.get(g.uid)
        houses = user.houses
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取数据失败')
    # 将查询到的房屋信息转换为字典存放到列表中
    houses_list = []
    if houses:
        for house in houses:
            houses_list.append(house.to_dict())
    return jsonify(errno=RET.OK, errmsg='OK', data={'houses': houses_list})


@api.route('/houses/<int:house_id>', methods=['GET'])
def get_house_detail(house_id):
    """获取房屋详情信息"""
    # 用户id
    uid = session.get('uid', -1)
    # 校验参数
    if not house_id:
        return jsonify(errno=RET.PARAMERR, errmsg='缺失参数')
    # 从redis中获取信息
    try:
       house_info = redis_store.get('house_info_%s' % house_id)
    except Exception as e:
        current_app.logger.error(e)
        house_info = None
    print(house_info)
    if house_info:
        return jsonify(errno=RET.OK, errmsg='redis请求成功', data={'uid': uid, 'info': house_info})
    # redis中没有该房屋信息
    # 重新查询数据库
    try:
       house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询数据出错')
    if not house:
        return jsonify(errno=RET.DATAEXIST, errmsg='房屋不存在')
    # 将房屋对象转换为字典
    house_data = house.to_detail_dict()
    # 存入redis
    house_json = json.dumps(house_data)
    redis_store.setex('house_info_%s' % house_id, constants.HOUSE_DETAIL_REDIS_EXPIRE_SECOND, house_json)
    # 返回数据
    return jsonify(errno=RET.OK, errmsg='db请求成功', data={'uid': uid, 'info': house_json})

